package com.tutos.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

public abstract class BaseDAO<T> {
	
	protected static EntityManagerFactory emf = EMF.get();
	
	public void insertEntity(T entity){
		EntityManager entityManager = emf.createEntityManager();
		entityManager.getTransaction().begin();
		
		entityManager.persist(entity);
		
		entityManager.getTransaction().commit();
		
		entityManager.close();
	}
	
	public void updateEntity(T entity){
		EntityManager entityManager = emf.createEntityManager();
		entityManager.getTransaction().begin();
		entityManager.merge(entity);
		entityManager.getTransaction().commit();
		entityManager.close();
	}
	
	public void removeEntity(T entity){
		EntityManager entityManager = emf.createEntityManager();
		entityManager.getTransaction().begin();
		entityManager.remove(entity);
		entityManager.getTransaction().commit();
		entityManager.close();
	}
	
    @SuppressWarnings({ "unchecked", "rawtypes" })
	protected List<T> search(String queryText, QParameter... params){
        EntityManager em = emf.createEntityManager();
               
        try {
                Query q = em.createNamedQuery(queryText);

                if (params != null) {
                        for (QParameter<String, Object> parameter : params) {
                                q.setParameter(parameter.getKey(), parameter.getValue());
                        }
                }
                                               
                return q.getResultList();              
        } finally {
                em.close();
        }
    }
	
	@SuppressWarnings("unchecked")
	public T getEntity(Object key){
		Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    	
    	EntityManager entityManager = emf.createEntityManager();
		T object = entityManager.find(persistentClass, key);
		
		return object;
	}
	
	public abstract List<T> getAll();
 
	
}
